home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Programming / MuManual / C_Sources / IndirectTest.c < prev    next >
C/C++ Source or Header  |  2000-03-22  |  10KB  |  324 lines

  1. /*********************************************************
  2.  ** IndirectTest                                        **
  3.  **                                                     **
  4.  ** Test indirect page descriptors of the MuLib         **
  5.  ** Release 1.01                                        **
  6.  **                                                     **
  7.  ** © 19.03.2000 Thomas Richter                         **
  8.  *********************************************************/
  9.  
  10. /// Includes
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <dos/dos.h>
  14. #include <mmu/context.h>
  15. #include <mmu/mmutags.h>
  16. #include <mmu/descriptor.h>
  17.  
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <proto/mmu.h>
  21.  
  22. #include <string.h>
  23. ///
  24. /// Defines
  25. ///
  26. /// Protos
  27. int __saveds main(void);
  28. int RunTests(void);
  29. void DumpData(UBYTE *src,ULONG size);
  30. ///
  31. /// Statics
  32. char version[]="$VER: IndirectTest 1.01 (19.03.2000) © THOR";
  33. struct ExecBase         *SysBase;
  34. struct DosLibrary       *DOSBase;
  35. struct MMUBase          *MMUBase;
  36. ///
  37.  
  38. ///main
  39. int __saveds main(void)
  40. {
  41. int rc=25;
  42.  
  43.         /*
  44.         ** Since we want to link without startup code,
  45.         ** we need to open the system libraries here...
  46.         */
  47.         SysBase = *((struct ExecBase **)(4L));
  48.  
  49.         /*
  50.         ** Open DOS and MMU
  51.         **/
  52.  
  53.         if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37L)) {
  54.                 if (MMUBase = (struct MMUBase *)OpenLibrary("mmu.library",42L)) {
  55.  
  56.                         rc = RunTests();
  57.  
  58.                         CloseLibrary((struct Library *)MMUBase);
  59.                 } else {
  60.                         Printf("IndirectTest failed: This program requires the mmu.library V42 or better.\n");
  61.                         rc = 10;
  62.                 }
  63.  
  64.                 /*
  65.                 ** Everything above 64 is a system
  66.                 ** error code we print over the console.
  67.                 */
  68.  
  69.                 if (rc>64) {
  70.                         PrintFault((LONG)rc,"IndirectTest failed");
  71.                         rc = 10;
  72.                 }
  73.                 CloseLibrary((struct Library *)DOSBase);
  74.         }
  75.  
  76.         return rc;
  77. }
  78. ///
  79. /// RunTests
  80. int RunTests(void)
  81. {
  82. struct MMUContext *ctx;
  83. struct MinList *ctxl;
  84. ULONG pagesize;
  85. ULONG *descriptor,*descriptorp;
  86. ULONG values[2];
  87. ULONG props[2];
  88. UBYTE *page,*pagep[2];
  89. int rc=25;
  90.  
  91.         /*
  92.         ** Get the context we're currently using
  93.         ** and its page size
  94.         ** furthermore, allocate a page.
  95.         */
  96.  
  97.         ctx             = CurrentContext(NULL);
  98.         pagesize        = GetPageSize(ctx);
  99.         page            = AllocAligned(pagesize*2,MEMF_PUBLIC|MEMF_CLEAR,pagesize);
  100.  
  101.         if (page) {
  102.  
  103.          /*
  104.          ** Now allocate memory for the descriptor
  105.          ** this must be long-word aligned, hence
  106.          ** an AllocMem is fine here.
  107.          ** However, we need to know the physical location
  108.          ** of the descriptor.
  109.          */
  110.          descriptor     = AllocMem(sizeof(ULONG),MEMF_PUBLIC);
  111.  
  112.          if (descriptor) {
  113.  
  114.  
  115.           /*
  116.           ** Compute physical locations
  117.           ** We do not assume that PhysicalLocation()
  118.           ** truncates the address. All values are
  119.           ** long/page aligned longs/pages, hence never cross a
  120.           ** page boundary.
  121.           */
  122.  
  123.           descriptorp    = descriptor;
  124.           PhysicalLocation(ctx,(void **)&descriptorp,&pagesize);
  125.  
  126.           /* And now for the pages */
  127.  
  128.           pagep[0]       = page;
  129.           props[0]       = PhysicalLocation(ctx,(void **)&pagep[0],&pagesize);
  130.           pagep[1]       = page+pagesize;
  131.           props[1]       = PhysicalLocation(ctx,(void **)&pagep[1],&pagesize);
  132.  
  133.  
  134.           if (pagep[0] && pagep[1] && descriptorp) {
  135.  
  136.            /*
  137.            ** Lock the context and make a backup of it.
  138.            **
  139.            */
  140.            LockMMUContext(ctx);
  141.  
  142.            if (ctxl=GetMapping(ctx)) {
  143.  
  144.                 /*
  145.                 ** Pre-calculate the values for the descriptors.
  146.                 ** The first descriptor maps the page to its TRUE physical
  147.                 ** location, the second one to the ROM, writeprotecting
  148.                 ** it.
  149.                 ** Note that we need to use the physical addresses here.
  150.                 **
  151.                 ** MAPP_ROM protection must be archived by setting this
  152.                 ** property bit "one level up".
  153.                 **
  154.                 ** We furthermore set USED and MODIFIED to avoid unnecessary
  155.                 ** MMU writebacks, and transfer the old properties back
  156.                 ** into the descriptor properties
  157.                 **
  158.                 ** Note that this call returns BAD_DESCRIPTOR in case
  159.                 ** of an error, not NULL.
  160.                 */
  161.  
  162.                 values[0] = BuildIndirect(ctx,(ULONG)(pagep[0]),props[0]|MAPP_USED|MAPP_MODIFIED);
  163.                 values[1] = BuildIndirect(ctx,(ULONG)(pagep[1]),props[1]|MAPP_USED|MAPP_WRITEPROTECTED);
  164.  
  165.                 if ((values[0] != BAD_DESCRIPTOR) &&
  166.                     (values[1] != BAD_DESCRIPTOR)) {
  167.                  /*
  168.                  ** Install the descriptor
  169.                  ** The first parameter is the physical address
  170.                  ** of the descriptor, the second the
  171.                  ** logical address of the page
  172.                  ** and the last the descriptor to install
  173.                  */
  174.  
  175.                  SetIndirect(descriptorp,(ULONG)page,values[0]);
  176.  
  177.                  /*
  178.                  ** Now install this descriptor
  179.                  ** We set this to MAPP_ROM because we want emulated
  180.                  ** ROM writeprotection.
  181.                  ** This is ignored if the descriptor itself is
  182.                  ** not write protected anyhow.
  183.                  ** We need the physical location of the descriptor
  184.                  ** here.
  185.                  */
  186.  
  187.                  if (SetProperties(ctx,MAPP_ROM|MAPP_INDIRECT,MAPP_ROM|MAPP_INDIRECT,
  188.                                       (ULONG)page,pagesize,
  189.                                       MAPTAG_DESCRIPTOR,descriptorp,
  190.                                       TAG_DONE)) {
  191.  
  192.                   if (RebuildTree(ctx)) {
  193.  
  194.                    /* Everything's fine.
  195.                    ** copy some dummy data into the page
  196.                    */
  197.                    memset(page,'*',(size_t)pagesize);
  198.  
  199.                    /* now print parts of it */
  200.                    DumpData(page,0x10);
  201.  
  202.                    /*
  203.                    ** install the other descriptor
  204.                    */
  205.                    SetIndirect(descriptorp,(ULONG)page,values[1]);
  206.  
  207.                    /*
  208.                    ** Dump it again. Should be all zero now.
  209.                    */
  210.                    DumpData(page,0x10);
  211.  
  212.                    /* Try to write to it. This should
  213.                    ** fail quietly.
  214.                    */
  215.  
  216.                    *page = 'A';
  217.  
  218.                    /* And dump it again */
  219.                    DumpData(page,0x10);
  220.  
  221.                    /*
  222.                    ** install the old descriptor
  223.                    ** again
  224.                    */
  225.                    SetIndirect(descriptorp,(ULONG)page,values[0]);
  226.  
  227.                    /*
  228.                    ** Now reset the context data.
  229.                    ** Disable the MAPP_ROM and MAPP_INDIRECT
  230.                    ** features. This call shouldn't fail or
  231.                    ** we are in trouble
  232.                    */
  233.  
  234.                    if (SetProperties(ctx,0,MAPP_ROM|MAPP_INDIRECT,
  235.                                     (ULONG)page,pagesize,TAG_DONE)) {
  236.  
  237.                         /* Restore the former MMU tree */
  238.                         if (RebuildTree(ctx)) {
  239.  
  240.                                 /*
  241.                                 ** everything is fine now.
  242.                                 */
  243.                                 rc = 0;
  244.                         }
  245.                    }
  246.  
  247.                    if (rc) {
  248.                         /*
  249.                         ** We're now in trouble.
  250.                         ** The old context couldn't be restored.
  251.                         ** Therefore, we do not release the descriptors
  252.                         ** such that the accesses are at least right,
  253.                         ** and restore the high-level by SetPropertyList()
  254.                         ** below. This will cause a mild memory leak,
  255.                         ** but the system will be fine.
  256.                         */
  257.                         Printf("IndirectTest: Can't restore the context.\n");
  258.                         descriptor = NULL;
  259.                    }
  260.                   }  else Printf("IndirectTest: Building the context failed.\n");
  261.                  } else Printf("IndirectTest: Can't install the new descriptor.\n");
  262.  
  263.                  /*
  264.                  ** In case of an error, we restore now the high
  265.                  ** level of the context.
  266.                  ** This is all we could do.
  267.                  ** The high-level looks then fine again,
  268.                  ** and the low level contains either an
  269.                  ** indirect descriptor which we can't get
  270.                  ** rid of, but which maps ok, or is
  271.                  ** unchanged. The system will be fine
  272.                  ** in both cases.
  273.                  */
  274.  
  275.                  if (rc) {
  276.                         SetPropertyList(ctx,ctxl);
  277.                  }
  278.  
  279.                 } else Printf("Can't build the new descriptors.\n");
  280.                 /* Release the mapping */
  281.                 ReleaseMapping(ctx,ctxl);
  282.  
  283.            } else rc = ERROR_NO_FREE_STORE;
  284.  
  285.            /*
  286.            ** Release the MMU Context lock
  287.            */
  288.            UnlockMMUContext(ctx);
  289.  
  290.           } else Printf("IndirectTest: Can't perform the logical to physical translation.\n");
  291.  
  292.           /*
  293.           ** now release the descriptor
  294.           */
  295.           if (descriptor) {
  296.                   FreeMem(descriptor,sizeof(ULONG));
  297.           }
  298.          } else rc = ERROR_NO_FREE_STORE; /* of if descriptor */
  299.  
  300.          FreeMem(page,pagesize*2);
  301.         } else rc = ERROR_NO_FREE_STORE; /* of if page */
  302.  
  303.         return rc;
  304. }
  305. ///
  306. /// DumpData
  307. void DumpData(UBYTE *src,ULONG size)
  308. {
  309.         /*
  310.         ** A pretty dumb memory dump
  311.         */
  312.  
  313.         Printf("Memory contents at 0x%08lx : ",src);
  314.         while(size) {
  315.                 Printf("%02lx ",*src);
  316.                 src++;
  317.                 size--;
  318.         }
  319.         Printf("\n");
  320. }
  321. ///
  322.  
  323.  
  324.